package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;
	@Autowired
	private TrackStatMapper trackStatMapper;
	@Autowired
	private AlbumInfoMapper albumInfoMapper;
	@Autowired
	private VodService vodService;
	@Autowired
	private UserInfoFeignClient userInfoFeignClient;

	/**
	 * 保存声音
	 * @param trackInfoVo
	 * @param userId
	 */
	@Override
	public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
		//创建声音对象
		TrackInfo trackInfo = new TrackInfo();
		//赋值
		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		trackInfo.setUserId(userId);
		//获取专辑对象
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		//设置order_num
		trackInfo.setOrderNum(albumInfo.getIncludeTrackCount()+1);
		//获取流媒体
		TrackMediaInfoVo trackMediaInfoVo= vodService.getMediaInfo(trackInfoVo.getMediaFileId());
		if (trackMediaInfoVo!=null){
			trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
			trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
			trackInfo.setMediaSize((trackMediaInfoVo.getSize()));
			trackInfo.setMediaType(trackMediaInfoVo.getType());
		}
		//保存声音信息
		trackInfoMapper.insert(trackInfo);
		//专辑里面的声音总数
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()+1);
		albumInfoMapper.updateById(albumInfo);
		//保存统计
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY);
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT);
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE);
		this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT);
	}

	private void saveTrackStat(Long id, String trackStatPlay) {
		//创建声音统计对象
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(id);
		trackStat.setStatType(trackStatPlay);
		trackStat.setStatNum(new Random().nextInt(10000));
		//保存声音统计
		trackStatMapper.insert(trackStat);
	}

	/**
	 * 分页查询用户声音
	 * @param page
	 * @param trackInfoQuery
	 * @return
	 */
	@Override
	public Page<TrackListVo> findUserTrackPage(Page<TrackListVo> page, TrackInfoQuery trackInfoQuery) {
		return trackInfoMapper.findUserTrackPage(page,trackInfoQuery);
	}

	/**
	 * 删除声音
	 * @param trackId
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeTrackInfo(Long trackId) {
		//获取声音信息
		TrackInfo trackInfo = getById(trackId);
		removeById(trackId);
		//删除声音统计
		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId,trackId));
		//修改专辑总数
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()-1);
		albumInfoMapper.updateById(albumInfo);
		//维护order_num
		trackInfoMapper.updateOrderNum(trackInfo.getAlbumId(),trackInfo.getOrderNum());
		try {
			//删除流媒体
			vodService.removeTrack(trackInfo.getMediaFileId());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 修改声音
	 * @param trackId
	 * @param trackInfoVo
	 */
	@Override
	public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {
		TrackInfo trackInfo = getById(trackId);
		//获取流媒体
		String mediaFileId = trackInfo.getMediaFileId();
		//拷贝
		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		if (!mediaFileId.equals(trackInfoVo.getMediaFileId())){//修改了
			//删除原有云点播
			vodService.removeTrack(mediaFileId);
			//获取新的云点播
			TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
			trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
			trackInfo.setMediaDuration(mediaInfo.getDuration());
			trackInfo.setMediaType(mediaInfo.getType());
			trackInfo.setMediaSize(mediaInfo.getSize());
		}
		//更新声音
		trackInfoMapper.updateById(trackInfo);
	}

	/**
	 * 分页查询专辑下的声音
	 * @param page
	 * @param albumId
	 * @param userId
	 * @return
	 */
	@Override
	public IPage<AlbumTrackListVo> findAlbumTrackPage(IPage<AlbumTrackListVo> page, Long albumId, Long userId) {
		//获取声音列表
		IPage<AlbumTrackListVo> albumTrackListVoIPage = trackInfoMapper.selectAlbumTrackPage(page,albumId);
		//获取专辑对象
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		//判断用户是否登录
		if (null == userId){
			//未登录 判断专辑类型
			String payType = albumInfo.getPayType();
			if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)) {//vip免费 付费
				//获取免费试看集数
				Integer tracksForFree = albumInfo.getTracksForFree();
				//设置超过免费集数付费
				albumTrackListVoIPage.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum()>tracksForFree)
						.forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
			}
		}else {
			//用户登录 获取用户信息
			Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
			Assert.notNull(userInfoVoResult, "用户信息不存在");
			UserInfoVo userInfoVo = userInfoVoResult.getData();
			Assert.notNull(userInfoVo, "用户信息不存在");
			//声明付费标识
			boolean isPaid=false;
			//判断是vip免费
			if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(albumInfo.getPayType())){
				//判断是否是vip 不是vip或者vip过期
				if (userInfoVo.getIsVip() == 0 || userInfoVo.getIsVip() == 1 && userInfoVo.getVipExpireTime().before(new Date())){
					isPaid = true;
				}
			}else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(albumInfo.getPayType())){//付费
				isPaid = true;
			}
			//付费情况
			if (isPaid){
				//获取免费试看集数
				Integer tracksForFree = albumInfo.getTracksForFree();
				//获取付费集数
				List<AlbumTrackListVo> albumTrackListVoList  = albumTrackListVoIPage.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree).collect(Collectors.toList());
				//获取需要付费的id
				List<Long> isNeedPaidTrackIdList  = albumTrackListVoList.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
				//通过远程调用 判断用户是否购买过专辑或者声音
				Result<Map<Long, Integer>> mapResult = userInfoFeignClient.userIsPaidTrack(albumId, isNeedPaidTrackIdList);
				Assert.notNull(mapResult, "用户信息不存在");
				Map<Long, Integer> map = mapResult.getData();
				Assert.notNull(map, "用户信息不存在");
				for (AlbumTrackListVo albumTrackListVo : albumTrackListVoList) {
					boolean flag = map.get(albumTrackListVo.getTrackId())==1?false:true;
					albumTrackListVo.setIsShowPaidMark(flag);
				}
			}
		}
			return albumTrackListVoIPage;
	}

	/**
	 * 更新声音播放量
	 * @param statMqVo
	 */
	@Override
	public void updateTrackStat(TrackStatMqVo statMqVo) {
		//声音播放量+1
		trackStatMapper.updateTrackStat(statMqVo.getTrackId(),statMqVo.getStatType(),statMqVo.getCount());
		if (SystemConstant.TRACK_STAT_PLAY.equals(statMqVo.getStatType())){
			//专辑播放量
			albumInfoMapper.updateTrackStat(statMqVo.getAlbumId(),SystemConstant.TRACK_STAT_PLAY,statMqVo.getCount());
		}
	}
}
